home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
raytrace
/
rayshade
/
graphtal.lzh
/
Graphtal.Amiga
/
Production.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-19
|
3KB
|
105 lines
/*
* Production.C - methods for L-System productions.
*
* Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
* University of Berne, Switzerland
* All rights reserved.
*
* This software may be freely copied, modified, and redistributed
* provided that this copyright notice is preserved on all copies.
*
* You may not distribute this software, in whole or in part, as part of
* any commercial product without the express consent of the authors.
*
* There is no warranty or other guarantee of fitness of this software
* for any purpose. It is provided solely "as is".
*
*/
#include <stdlib.h>
#include "Production.h"
#include "Error.h"
implementList(ProductionList, ProductionPtr);
//___________________________________________________________ Production
Production::Production(Predecessor* p, Expression* c, SuccessorList* s)
: _name(p->name), predecessor(p), condition(c), successors(s)
{
arg_count = (p->formalParam) ? (int)p->formalParam->count()
: 0;
stochastic = (successors->count() > 1);
}
Production::~Production()
{
delete predecessor;
if (condition) delete condition;
for (long i=0; i<successors->count(); i++)
delete successors->item(i);
delete successors;
}
// choose a successor out of the successor list and clone it
ModuleList* Production::cloneSuccessor()
{
// if we have more than one successor, choose by random
if (stochastic) {
double p = drand48();
for (register long i=0; i<successors->count(); i++)
if (p <= successors->item(i)->probability())
return successors->item(i)->clone();
// No successor choosen. VERY, VERY BAD!
Error(ERR_PANIC, "cloneSuccessor: no successor choosen");
return NULL;
}
else
return successors->item(0)->clone();
}
// The probabilities of the successor must cumulate to 1. In addition
// a preprocessing is done, e.g.:
// A -> (0.5) B => A -> (0.5) B
// -> (0.5) C -> (1.0) C
// => no arithmetic operation has to be performed will choosing a
// successor
int Production::cumulateProbability()
{
double sum = 0.0;
for (long i=0; i<successors->count(); i++) {
sum += successors->item(i)->probability();
successors->item(i)->probability() = sum;
}
return ((sum > 1.01) ? 1 : 0);
}
int Production::hashValue()
{
extern unsigned int modHash(const char*, long);
return modHash((const char*)_name, (long)arg_count);
}
ostream& operator<<(ostream& os, Production& p)
{
long i;
os << p.predecessor->name;
if (p.predecessor->formalParam) {
os << '(';
for (i=0; i<p.predecessor->formalParam->count()-1; i++)
os << *p.predecessor->formalParam->item(i) << ", ";
os << *p.predecessor->formalParam->item(i) << ")";
}
if (p.condition) os << " : " << *p.condition << ' ';
for (i=0; i<p.successors->count()-1; i++)
os << *p.successors->item(i) << "\n\t";
os << *p.successors->item(i) << '\n';
return os;
}